import { useEffect, useRef, useState } from 'react'

interface SliderCaptchaCanvasProps {
  width?: number
  height?: number
  pieceSize?: number
  tolerance?: number
  onSuccess: () => void
  onCancel: () => void
}

// 简洁的 Canvas 缺口拼图实现（矩形缺口）
export default function SliderCaptchaCanvas({
  width = 320,
  height = 180,
  pieceSize = 50,
  tolerance = 8,
  onSuccess,
  onCancel
}: SliderCaptchaCanvasProps) {
  const bgCanvasRef = useRef<HTMLCanvasElement>(null)
  const pieceCanvasRef = useRef<HTMLCanvasElement>(null)
  const [gapX, setGapX] = useState(0)
  const [gapY, setGapY] = useState(0)
  const [dragX, setDragX] = useState(0)
  const startXRef = useRef(0)
  const draggingRef = useRef(false)
  const barDraggingRef = useRef(false)

  // 生成图片并绘制
  const regenerate = async () => {
    const img = new Image()
    img.crossOrigin = 'anonymous'
    img.src = `https://picsum.photos/${width * 2}/${height * 2}?random=${Date.now()}`
    await new Promise(resolve => { img.onload = resolve })

    const bg = bgCanvasRef.current!
    const piece = pieceCanvasRef.current!
    const bgCtx = bg.getContext('2d')!
    const pieceCtx = piece.getContext('2d')!

    bg.width = width
    bg.height = height
    piece.width = pieceSize
    piece.height = pieceSize

    bgCtx.clearRect(0, 0, width, height)
    pieceCtx.clearRect(0, 0, pieceSize, pieceSize)

    bgCtx.drawImage(img, 0, 0, width, height)

    const gx = Math.floor(60 + Math.random() * (width - pieceSize - 90))
    const gy = Math.floor(30 + Math.random() * (height - pieceSize - 60))
    setGapX(gx)
    setGapY(gy)
    setDragX(0)

    // 背景挖洞（白色高亮缺口边缘）
    bgCtx.save()
    bgCtx.globalCompositeOperation = 'destination-out'
    bgCtx.fillRect(gx, gy, pieceSize, pieceSize)
    bgCtx.restore()
    bgCtx.strokeStyle = 'rgba(255, 77, 79, 0.8)'
    bgCtx.lineWidth = 3
    bgCtx.strokeRect(gx + 1.5, gy + 1.5, pieceSize - 3, pieceSize - 3)

    // 拼图块内容
    const scaleX = img.width / width
    const scaleY = img.height / height
    pieceCtx.drawImage(
      img,
      gx * scaleX,
      gy * scaleY,
      pieceSize * scaleX,
      pieceSize * scaleY,
      0,
      0,
      pieceSize,
      pieceSize
    )
    pieceCtx.strokeStyle = 'rgba(255, 77, 79, 0.8)'
    pieceCtx.lineWidth = 3
    pieceCtx.strokeRect(1.5, 1.5, pieceSize - 3, pieceSize - 3)
  }

  useEffect(() => {
    regenerate()
  }, [])

  const onDown = (clientX: number) => {
    draggingRef.current = true
    startXRef.current = clientX
  }

  const onMove = (clientX: number) => {
    if (!draggingRef.current && !barDraggingRef.current) return
    const delta = clientX - startXRef.current
    const min = 0
    const max = width - pieceSize
    const next = Math.max(min, Math.min(max, delta))
    setDragX(next)
  }

  const onUp = () => {
    if (!draggingRef.current && !barDraggingRef.current) return
    draggingRef.current = false
    barDraggingRef.current = false
    const passed = Math.abs(dragX - gapX) <= tolerance
    if (passed) onSuccess()
    else setDragX(0)
  }

  // 滑块条交互
  const onBarDown = (clientX: number) => {
    barDraggingRef.current = true
    startXRef.current = clientX - dragX
  }
  const onBarMove = (clientX: number) => {
    if (!barDraggingRef.current) return
    const min = 0
    const max = width - pieceSize
    const next = clientX - startXRef.current
    setDragX(Math.max(min, Math.min(max, next)))
  }

  return (
    <div style={{ width, userSelect: 'none' }}>
      <div style={{ position: 'relative', width, height, borderRadius: 8, overflow: 'hidden', boxShadow: '0 4px 16px rgba(0,0,0,.12)' }}>
        <canvas ref={bgCanvasRef} />
        <canvas
          ref={pieceCanvasRef}
          style={{ position: 'absolute', top: gapY, left: dragX, cursor: 'grab' }}
          onMouseDown={(e) => onDown(e.clientX)}
          onMouseMove={(e) => onMove(e.clientX)}
          onMouseUp={onUp}
          onMouseLeave={onUp}
          onTouchStart={(e) => onDown(e.touches[0].clientX)}
          onTouchMove={(e) => onMove(e.touches[0].clientX)}
          onTouchEnd={onUp}
        />
      </div>
      {/* 滑块控制条 */}
      <div style={{ marginTop: 12, height: 44, position: 'relative' }}>
        <div style={{ height: 44, borderRadius: 22, background: '#f5f5f5', border: '1px solid #e5e5e5' }}></div>
        <div
          style={{
            position: 'absolute',
            top: 0,
            left: 0,
            height: 44,
            width: (dragX + pieceSize),
            borderRadius: 22,
            background: 'rgba(24,144,255,0.2)'
          }}
        />
        <div
          style={{
            position: 'absolute',
            top: 2,
            left: dragX,
            width: pieceSize,
            height: 40,
            background: '#fff',
            borderRadius: 20,
            border: '2px solid #1890ff',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            cursor: 'grab',
            boxShadow: '0 2px 8px rgba(24,144,255,.25)'
          }}
          onMouseDown={(e) => onBarDown(e.clientX)}
          onMouseMove={(e) => onBarMove(e.clientX)}
          onMouseUp={onUp}
          onMouseLeave={onUp}
          onTouchStart={(e) => onBarDown(e.touches[0].clientX)}
          onTouchMove={(e) => onBarMove(e.touches[0].clientX)}
          onTouchEnd={onUp}
        >
          <span style={{ color: '#1890ff' }}>&rarr;</span>
        </div>
        <div style={{ position: 'absolute', left: 0, right: 0, top: 0, height: 44, display: 'flex', alignItems: 'center', justifyContent: 'center', pointerEvents: 'none', color: '#8c8c8c' }}>
          向右拖动完成拼图
        </div>
      </div>
      <div style={{ display: 'flex', gap: 8, marginTop: 10 }}>
        <button onClick={regenerate} style={{ padding: '6px 12px' }}>刷新</button>
        <button onClick={onCancel} style={{ padding: '6px 12px' }}>取消</button>
      </div>
    </div>
  )
}


